<template>
  <div>
    <el-row>
      <h4><b>审批人设置</b></h4>
      <el-radio-group v-model="dataType" @change="changeDataType">
        <el-radio label="USERS">指定用户</el-radio>
        <el-radio label="ROLES">部门角色</el-radio>
        <el-radio label="POSTS">部门岗位</el-radio>
        <el-radio label="INITIATOR">发起人</el-radio>
      </el-radio-group>
    </el-row>
    <el-row>
      <div v-if="dataType === 'USERS'">
        <el-tag
          v-for="(item, index) in userNames"
          :key="'user_name_' + index"
          effect="plain"
          style="margin-right:5px;"
        >
          {{ item }}
        </el-tag>
        <div class="element-drawer__button">
          <el-button class="fr" size="mini" icon="el-icon-search" @click="selectUser">选择用户</el-button>
        </div>
      </div>
      <div v-if="dataType === 'ROLES'">
        <el-tag
          v-for="(item, index) in roleNames"
          :key="'role_name_' + index"
          effect="plain"
          style="margin-right:5px;"
        >
          {{ item }}
        </el-tag>
        <el-button class="fr" size="mini" icon="el-icon-search" @click="selectRole">选择角色</el-button>
      </div>
      <div v-if="dataType === 'POSTS'">
        <el-select v-model="postIds" clearable filterable multiple placeholder="选择岗位" @change="changePost">
          <el-option
            v-for="item in optionOfPost"
            :key="'user_post_' + item.id"
            :label="item.text"
            :value="item.id"
          />
        </el-select>
      </div>
    </el-row>
    <el-row>
      <div v-show="showMultiFlog">
        <el-divider />
        <h4><b>多实例审批方式</b></h4>
        <el-row>
          <el-radio-group v-model="multiLoopType" @change="changeMultiLoopType">
            <el-row><el-radio label="Null">无</el-radio></el-row>
            <el-row><el-radio label="SequentialMultiInstance">会签（需所有审批人同意）</el-radio></el-row>
            <el-row><el-radio label="ParallelMultiInstance">或签（一名审批人同意即可）</el-radio></el-row>
          </el-radio-group>
        </el-row>
        <el-row v-if="multiLoopType !== 'Null'">
          <el-tooltip content="开启后，实例需按顺序轮流审批" placement="top-start" @click.stop.prevent>
            <i class="header-icon el-icon-info"></i>
          </el-tooltip>
          <span class="custom-label">顺序审批：</span>
          <el-switch v-model="isSequential" @change="changeMultiLoopType" />
        </el-row>
      </div>
    </el-row>

    <user-table-dialog v-if="openUserDialog" ref="userDialog" :single="false" @confirmDialog="setUser" />
    <role-tree-dialog v-if="openRoleDialog" ref="roleDialog" :single="false" @confirmDialog="setRole" />
  </div>
</template>

<script>
import { postSelectData } from '@/api/system/post'
import UserTableDialog from '@/views/system/user/table/selectDialog'
import RoleTreeDialog from '@/views/system/role/tree/dialog'

const userTaskForm = {
  dataType: '',
  assignee: '',
  candidateUsers: '',
  candidateGroups: '',
  text: ''
}

export default {
  name: 'UserTask',
  components: {
    UserTableDialog,
    RoleTreeDialog
  },
  props: {
    id: String,
    type: String
  },
  data() {
    return {
      loading: false,
      dataType: 'USERS',
      userIds: [],
      userNames: [],
      roleIds: [],
      roleNames: [],
      postIds: [],
      optionOfPost: [],
      showMultiFlog: false,
      isSequential: false,
      multiLoopType: 'Null',
      openUserDialog: false,
      openRoleDialog: false
    }
  },
  mounted() {
    this.getPostData()
  },
  watch: {
    id: {
      immediate: true,
      handler() {
        this.bpmnElement = window.bpmnInstances.bpmnElement
        this.$nextTick(() => this.resetTaskForm())
      }
    }
  },
  beforeDestroy() {
    this.bpmnElement = null
  },
  methods: {
    getPostData() {
      postSelectData().then(response => {
        this.optionOfPost = response.param.data
      }).catch(e => {})
    },
    resetTaskForm() {
      const bpmnElementObj = this.bpmnElement?.businessObject
      if (!bpmnElementObj) {
        return
      }
      this.clearOptionsData()
      this.dataType = bpmnElementObj['dataType']
      if (this.dataType === 'USERS') {
        let userIdData = bpmnElementObj['candidateUsers'] || bpmnElementObj['assignee']
        let userText = bpmnElementObj['text'] || []
        if (userIdData && userIdData.toString().length > 0 && userText && userText.length > 0) {
          this.userIds = userIdData?.toString().split(',')
          this.userNames = userText?.split(',')
        }
        if (this.userIds.length > 1) {
          this.showMultiFlog = true
        }
      } else if (this.dataType === 'ROLES') {
        let roleIdData = bpmnElementObj['candidateGroups'] || []
        if (roleIdData && roleIdData.length > 0) {
          this.roleIds = roleIdData.split(',')
          this.getRoleNames()
        }
        this.showMultiFlog = true
      } else if (this.dataType === 'POSTS') {
        let postIdData = bpmnElementObj['candidateGroups'] || []
        if (postIdData && postIdData.length > 0) {
          this.postIds = postIdData.split(',')
        }
        this.showMultiFlog = true
      }
      this.getElementLoop(bpmnElementObj)
    },
    getRoleNames() {
      if (this.roleIds && this.roleIds.length > 0) {
        this.$http.get(`${process.env.VUE_APP_MODULE_ADMIN_API}/api/system/role/convertName?ids=` + this.roleIds.join(',')).then(response => {
          if (response.param)
            this.roleNames = response.param.split(',')
        })
      }
    },
    /**
     * 清空选项数据
     */
    clearOptionsData() {
      this.userIds = []
      this.userNames = []
      this.roleIds = []
      this.roleNames = []
      this.postIds = []
    },
    /**
     * 更新节点数据
     */
    updateElementTask() {
      const taskAttr = Object.create(null)
      for (let key in userTaskForm) {
          taskAttr[key] = userTaskForm[key]
      }
      window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr)
    },
    selectUser() {
      this.openUserDialog = true
      this.$nextTick(() => {
        this.$refs.userDialog.init()
      })
    },
    setUser(row) {
      if (!row || row.length <= 0) {
        this.$modal.msgError('请选择用户')
        return
      }

      userTaskForm.dataType = 'USERS'
      this.userIds = row.map(value => value.userId)
      this.userNames = row.map(value => value.userName)

      if (row.length === 1) {
        userTaskForm.assignee = row[0].userId
        userTaskForm.text = row[0].userName
        userTaskForm.candidateUsers = null
        this.showMultiFlog = false
        this.multiLoopType = 'Null'
        this.changeMultiLoopType(this.multiLoopType)
      } else {
        userTaskForm.candidateUsers = row.map(value => value.userId).join(',') || null
        userTaskForm.text = row.map(value => value.userName).join(',') || null
        userTaskForm.assignee = null
        this.showMultiFlog = true
      }

      this.updateElementTask()
    },
    selectRole() {
      this.openRoleDialog = true
      let selected = null
      if (this.roleIds.length > 0) {
        selected = this.roleIds.join(',')
      }

      this.$nextTick(() => {
        this.$refs.roleDialog.init(selected)
      })
    },
    setRole(nodes) {
      userTaskForm.dataType = 'ROLES'
      this.roleIds = nodes.map(node => node.id)
      this.roleNames = nodes.map(node => node.title)

      userTaskForm.candidateGroups = nodes.map(node => node.id).join(',') || null
      userTaskForm.text = nodes.map(node => node.title).join(',') || null
      this.updateElementTask()
    },
    changePost() {
      userTaskForm.dataType = 'POSTS'

      if (this.postIds && this.postIds.length > 0) {
        userTaskForm.candidateGroups = this.postIds.join(',') || null
        let ids = this.postIds
        userTaskForm.text = this.optionOfPost.filter(post => {
            return ids.indexOf(post.id) !== -1
          }).map(post => post.text).join() || null
        this.updateElementTask()
      }
    },
    changeDataType(val) {
      // 清空 userTaskForm 所有属性值
      Object.keys(userTaskForm).forEach(key => userTaskForm[key] = null)
      userTaskForm.dataType = val
      if (val === 'USERS') {
        if (this.userIds && this.userIds.length > 0) {
          if (this.userIds.length === 1) {
            userTaskForm.assignee = this.userIds[0]
          } else {
            userTaskForm.candidateUsers = this.userIds.join(',')
          }
          userTaskForm.text = this.userNames?.join(',') || null
        }
      } else if (val === 'ROLES') {
        if (this.roleIds && this.roleIds.length > 0) {
          userTaskForm.candidateGroups = this.roleIds.join(',') || null
          userTaskForm.text = this.roleNames.join(',') || null
        }
      } else if (val === 'POSTS') {
        if (this.postIds && this.postIds.length > 0) {
          userTaskForm.candidateGroups = this.postIds.join(',') || null
          let ids = this.postIds
          userTaskForm.text = this.optionOfPost.filter(post => {
            return ids.indexOf(post.id) !== -1
          }).map(post => post.text).join() || null
        }
      } else if (val === 'INITIATOR') {
        userTaskForm.assignee = '${initiator}'
        userTaskForm.text = '流程发起人'
      }
      this.updateElementTask()
      if (val === 'ROLES' || val === 'POSTS' || (val === 'USERS' && this.userIds.length > 1)) {
        this.showMultiFlog = true
      } else {
        this.showMultiFlog = false
      }
      this.multiLoopType = 'Null'
      this.changeMultiLoopType(this.multiLoopType)
    },
    getElementLoop(businessObject) {
      if (!businessObject.loopCharacteristics) {
        this.multiLoopType = "Null"
        return
      }
      this.isSequential = businessObject.loopCharacteristics.isSequential
      if (businessObject.loopCharacteristics.completionCondition) {
        if (businessObject.loopCharacteristics.completionCondition.body === '${nrOfCompletedInstances >= nrOfInstances}') {
          this.multiLoopType = 'SequentialMultiInstance'
        } else {
          this.multiLoopType = 'ParallelMultiInstance'

        }
      }
    },
    changeMultiLoopType(type) {
      // 取消多实例配置
      if (type === 'Null') {
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, { loopCharacteristics: null })
        return
      }
      this.multiLoopInstance = window.bpmnInstances.moddle.create('bpmn:MultiInstanceLoopCharacteristics', { isSequential: this.isSequential })
      // 更新多实例配置
      window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
        loopCharacteristics: this.multiLoopInstance,
        assignee: '${assignee}'
      })
      // 完成条件
      let completionCondition = null
      // 会签
      if (type === 'SequentialMultiInstance') {
        completionCondition = window.bpmnInstances.moddle.create('bpmn:FormalExpression', { body: '${nrOfCompletedInstances >= nrOfInstances}' })
      }
      // 或签
      if (type === 'ParallelMultiInstance') {
        completionCondition = window.bpmnInstances.moddle.create('bpmn:FormalExpression', { body: '${nrOfCompletedInstances > 0}' })
      }
      // 更新模块属性信息
      window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
        collection: '${multiInstanceHandler.multiAssignee(execution)}',
        elementVariable: 'assignee',
        completionCondition
      })
    },
  }
}
</script>

<style scoped lang="scss">
.el-row .el-radio-group {
  margin-bottom: 15px;
  .el-radio {
    line-height: 28px;
  }
}
.el-tag {
  margin-bottom: 10px;
  + .el-tag {
    margin-left: 10px;
  }
}

.custom-label {
  padding-left: 5px;
  font-weight: 500;
  font-size: 14px;
  color: #606266;
}

</style>
